package com.hub.frame.interceptor;

import com.hub.frame.exception.*;
import com.hub.utils.ApiResultObject;
import com.hub.frame.consts.ResultPacketCode;
import com.zyfkj.hub.frame.exception.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
@Aspect
@Order(2)
public class LogInterceptor {

    @Pointcut("execution(* com.zyfkj.*.controller.*.*(..))")
    public void log() {
    }

    @Around("log()")
    public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 查看权限是否验证通过
        if (request.getAttribute("permission") != null) {
            ApiResultObject<String> apiResult = (ApiResultObject<String>) request.getAttribute("permission");
            // 在这里抛出，下面的afterThrowing才会执行// 在这里抛出，下面的afterThrowing才会执行
            if (apiResult.getCode() == ResultPacketCode.APIResultCode.FrequentFail.getCode()) {
                throw new TooFrequentException(apiResult.getMessage());
            } else if (apiResult.getCode() == ResultPacketCode.APIResultCode.AuthFail.getCode()) {
                throw new AdminPermissionDeniedException(apiResult.getMessage());
            } else {
                throw new PermissionDeniedException(apiResult.getMessage());
            }
        }

        return joinPoint.proceed();
    }

    @AfterThrowing(value = "log()", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) {

        // 已知异常不需要写日志
        if (ex instanceof AdminPermissionDeniedException
                || ex instanceof CustomParamCheckException
                || ex instanceof TooFrequentException
                || ex instanceof TransactionRollBackException
                || ex instanceof BussinessException) {
            return;
        }

        //获得日志类logger的实例
        log.error(StringUtils.EMPTY, ex);
    }
}